package com.zywl.utils.utils;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.URLDecoder;
import java.util.Properties;

/**
 * 文件操作工具类
 *
 * @author yangfan
 */
public class FileUtil {
    private static Logger logger = Logger.getLogger(FileUtil.class);

    /**
     * 加载 properties 文件
     *
     * @param propPath
     * @return
     */
    public static Properties loadPropFile(String propPath) {
        Properties prop = new Properties();
        InputStream is = null;
        try {
            String suffix = ".properties";
            if (propPath.lastIndexOf(suffix) == -1) {
                propPath += suffix;
            }
            is = Thread.currentThread().getContextClassLoader().getResourceAsStream(propPath);
            if (is != null) {
                prop.load(is);
            }
        } catch (Exception e) {
            logger.error("加载 properties 文件出错！", e);
            throw new RuntimeException(e);
        } finally {
            try {
                if (is != null) {
                    is.close();
                }
            } catch (Exception e) {
                logger.error("加载 properties 文件出错！", e);
            }
        }
        return prop;
    }

    /**
     * 校验文的合法性
     *
     * @param filePath
     * @return
     * @throws Exception
     */
    public static boolean fileValidate(String filePath) throws Exception {

        if (StringUtils.isNotEmpty(filePath)) {
            File file = new File(filePath);
            return file.exists();
        }
        return false;
    }

    /**
     * 读取二进制数据从文件
     *
     * @param filePath
     * @return
     * @throws Exception
     */
    public static byte[] getByteFromFile(String filePath) throws Exception {
        byte[] b = {};
        if (fileValidate(filePath)) {
            File file = new File(filePath);
            if (file != null) {
                b = new byte[(int) file.length()];
                InputStream is = new FileInputStream(file);
                BufferedInputStream bi = new BufferedInputStream(is);
                bi.read(b);
                bi.close();
                is.close();
            }
        } else {
            logger.info("文件不合法");
        }
        return b;
    }

    /**
     * 读取文本数据从文件
     *
     * @param filePath
     * @return
     * @throws Exception
     */
    public static String getStringOfFile(String filePath) throws Exception {

        if (fileValidate(filePath)) {

            File file = new File(filePath);
            byte b[] = new byte[(int) file.length()];
            InputStream is = new FileInputStream(file);
            BufferedInputStream bi = new BufferedInputStream(is);
            bi.read(b);
            bi.close();
            is.close();
            return new String(b);

        } else {
            logger.info("文件不合法");
        }
        return null;
    }

    /**
     * 根据文件路径生成一个新的文件
     *
     * @param filePath
     * @return
     * @throws Exception
     */
    public static File newFile(String filePath) throws Exception {

        File file = new File(filePath);
        File dirFile = new File(file.getParent());
        if (!dirFile.exists()) {
            dirFile.mkdirs();
        }
        if (!file.exists()) {
            file.createNewFile();
        }
        return file;

    }

    /**
     * 删除文件 如果不是文件 或文件不存在 则返回失败
     *
     * @param filePath
     * @return
     * @throws IOException
     */
    public static boolean deleteFile(String filePath) throws IOException {
        File file = new File(filePath);
        if (file.exists() && file.isFile()) {
            return file.delete();
        } else {
            return false;
        }
    }

    /**
     * 获得本地不完整路径
     *
     * @return
     * @throws Exception
     */
    public static String getLocalPath() throws Exception {

        String localFilePath = FileUtil.class.getClassLoader().getResource("/").getPath();
        localFilePath = URLDecoder.decode(localFilePath.substring(1, localFilePath.indexOf("WEB-INF")), "UTF-8");
        return localFilePath;
    }

    /**
     * 写文件
     *
     * @return
     * @throws Exception
     */
    public static void writeFile(String str, String path) throws Exception {

        FileOutputStream fos = new FileOutputStream(path);
        OutputStreamWriter osw = new OutputStreamWriter(fos);
        BufferedWriter bw = new BufferedWriter(osw);
        bw.write(str);
        bw.close();
    }

    /**
     * 读文件
     *
     * @return
     * @throws Exception
     */
    public static String readFile(String path) throws Exception {

        FileInputStream fis = new FileInputStream(path);
        InputStreamReader isr = new InputStreamReader(fis);
        BufferedReader br = new BufferedReader(isr);
        String str = br.readLine();
        br.close();
        return str;

    }

    /**
     * 将文件File类型转为byte[]类型
     */
    public static byte[] File2byte(File file) {
        byte[] buffer = null;
        try {
            FileInputStream fis = new FileInputStream(file);
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            byte[] b = new byte[1024];
            int n;
            while ((n = fis.read(b)) != -1) {
                bos.write(b, 0, n);
            }
            fis.close();
            bos.close();
            buffer = bos.toByteArray();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return buffer;
    }

    /**
     * 删除某目录下文件名字包含指定字符的文件
     *
     * @param folder 文件目录
     * @param name   文件名（模糊）
     */
    public static void deleteFileByName(File folder, String name) {
        File[] files = folder.listFiles();
        if (files != null) {
            for (int i = 0; i < files.length; i++) {
                if (files[i].isDirectory()) {
                    deleteFileByName(files[i], name);
                }
                if (files[i].isFile()) {
                    String filename = files[i].getName();
                    if (filename.indexOf(name) != -1) {
                        files[i].delete();
                    }
                }
            }
        }
    }

    /**
     * 删除某目录下所有文件
     *
     * @param folder 文件目录
     */
    public static void deleteFolder(File folder) {
        File[] files = folder.listFiles();
        if (files != null) {
            for (int i = 0; i < files.length; i++) {
                if (files[i].isDirectory()) {
                    deleteFolder(files[i]);
                }
                if (files[i].isFile()) {
                    files[i].delete();
                }
            }
        }
        folder.delete();
    }

    /**
     * 文件重命名
     *
     * @param path    如 O:/haha/
     * @param oldname
     * @param newname
     */
    public static void renameFile(String path, String oldname, String newname) {
        if (!oldname.equals(newname)) {// 新的文件名和以前文件名不同时,才有必要进行重命名
            File oldfile = new File(path + oldname);
            File newfile = new File(path + newname);
            if (!oldfile.exists()) {
                return;// 重命名文件不存在
            }
            if (!newfile.exists()) {// 若在该目录下已经有一个文件和新文件名相同，则不允许重命名
                oldfile.renameTo(newfile);
            }
        }
    }

    /**
     * 文件夹重命名
     *
     * @param oldFolder 如 O:/haha/
     * @param newFolder
     */
    public static void renameFolder(String oldFolder, String newFolder) {
        if (oldFolder != null && !oldFolder.equals(newFolder)) {// 新的文件名和以前文件名不同时,才有必要进行重命名
            File old_folder = new File(oldFolder);
            File new_folder = new File(newFolder);
            if (!old_folder.exists()) {
                return;// 重命名文件不存在
            }
            if (new_folder.exists()) {// 若在该目录下已经有一个文件和新文件名相同，则不允许重命名
                deleteFolder(new_folder);
            }
            old_folder.renameTo(new_folder);
        }
    }

    /**
     * 根据文件模糊查询该文件名
     *
     * @param folder
     * @param name
     * @return
     */
    public static String getFileNameByName(File folder, String name) {
        File[] files = folder.listFiles();
        String filename = Constants.STRING_NULL;
        String fileName = Constants.STRING_NULL;
        if (files != null) {
            for (int i = 0; i < files.length; i++) {
                if (files[i].isDirectory()) {
                    getFileNameByName(files[i], name);
                }
                if (files[i].isFile()) {
                    filename = files[i].getName();
                    if (filename.indexOf(name) != -1) {
                        fileName += ";" + filename;
                    }
                }
            }
        }

        if (StringUtils.isNotEmpty(fileName)) {
            fileName = fileName.substring(1);
        }
        return fileName;
    }

    public static void copyFile(File sourcefile, File targetFile) throws IOException {
        // 新建文件输入流并对它进行缓冲
        FileInputStream input = new FileInputStream(sourcefile);
        BufferedInputStream inbuff = new BufferedInputStream(input);

        // 新建文件输出流并对它进行缓冲
        FileOutputStream out = new FileOutputStream(targetFile);
        BufferedOutputStream outbuff = new BufferedOutputStream(out);

        // 缓冲数组
        byte[] b = new byte[1024 * 5];
        int len = 0;
        while ((len = inbuff.read(b)) != -1) {
            outbuff.write(b, 0, len);
        }
        // 刷新此缓冲的输出流
        outbuff.flush();

        // 关闭流
        inbuff.close();
        outbuff.close();
        out.close();
        input.close();

    }

    public static void copyDirectiory(String sourceDir, String targetDir) throws IOException {
        // 新建目标目录
        (new File(targetDir)).mkdirs();
        // 获取源文件夹当下的文件或目录
        File[] file = (new File(sourceDir)).listFiles();

        for (int i = 0; i < file.length; i++) {
            if (file[i].isFile()) {
                // 源文件
                File sourceFile = file[i];
                // 目标文件
                File targetFile = new File(new File(targetDir).getAbsolutePath() + File.separator + file[i].getName());

                copyFile(sourceFile, targetFile);

            }

            if (file[i].isDirectory()) {
                // 准备复制的源文件夹
                String dir1 = sourceDir + file[i].getName();
                // 准备复制的目标文件夹
                String dir2 = targetDir + "/" + file[i].getName();

                copyDirectiory(dir1, dir2);
            }
        }
    }

    /**
     * 网站删除图片
     *
     * @param request
     * @param filePath
     * @return
     */
    public static void deleteFileForWeb(HttpServletRequest request, String filePath) throws Exception {
        if (StringUtils.isNotEmpty(filePath)) {
            StringBuilder sb = new StringBuilder();
            String realPath = request.getSession().getServletContext().getRealPath(File.separator);
            String path = request.getContextPath();
            if (StringUtils.isNotEmpty(path)) {
                path = path.replace(Constants.STRING_SPRIT, Constants.STRING_NULL);
            } else {
                path = Constants.ROOT;
            }
//            sb.append(realPath.substring(0, realPath.indexOf(path)));
            sb.append(realPath);
            sb.append(filePath);
            String ctxPath = sb.toString();
            FileUtil.deleteFile(ctxPath);
        }
    }

    public static String getRealPathForServer(HttpServletRequest request) {
        StringBuilder sb = new StringBuilder();
        String realPath = request.getSession().getServletContext().getRealPath(File.separator);
        String ctx = request.getContextPath();
        if (StringUtils.isNotEmpty(ctx)) {
            ctx = ctx.replace(Constants.STRING_SPRIT, Constants.STRING_NULL);
        } else {
            ctx = Constants.ROOT;
        }
        sb.append(realPath);
//        sb.append(realPath.substring(0, realPath.indexOf(ctx)));
        return sb.toString().replace(Constants.STRING_SPRIT, File.separator);
    }

    /**
     * D:\tomcat7\webapps\ + path
     *
     * @param request
     * @param path
     * @return
     */
    public static String getFileRealPathForServer(HttpServletRequest request, String path) {
        StringBuilder sb = new StringBuilder();
        String realPath = request.getSession().getServletContext().getRealPath(File.separator);
        String ctx = request.getContextPath();
        if (StringUtils.isNotEmpty(ctx)) {
            ctx = ctx.replace(Constants.STRING_SPRIT, Constants.STRING_NULL);
        } else {
            ctx = Constants.ROOT;
        }
//        sb.append(realPath.substring(0, realPath.indexOf(ctx)));
        sb.append(realPath);
        sb.append(path.replace(Constants.STRING_SPRIT, File.separator));
        return sb.toString().replace(Constants.STRING_SPRIT, File.separator);
    }

    public static String getFileName(String fileName){
        fileName = fileName.replace("\\", "/");
        int index = fileName.lastIndexOf(Constants.STRING_SPRIT);
        if(index == -1){
            return fileName;
        }
        return fileName.substring(index + 1);
    }
}
